package com.dangdang.recursion;

import com.dangdang.model.CombinationCoupons;
import com.dangdang.model.CouponInfo;
import com.dangdang.model.Money;
import com.dangdang.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import java.util.*;

public class CouponHadle {

    private static final Logger log = LoggerFactory.getLogger(CouponHadle.class);

    private List<CombinationCoupons> descartes(List<List<CouponInfo>> dimValue) {
        List<CombinationCoupons> couponCombinations = new ArrayList<CombinationCoupons>();
        List<List<CouponInfo>> result = new ArrayList<>();
        if (dimValue == null || dimValue.size() == 0)
            return couponCombinations;
        backtrace(dimValue, 0, result, new ArrayList<CouponInfo>());
        for(List<CouponInfo> couponInfos:result){
            CombinationCoupons combination = new CombinationCoupons();
            combination.setCouponInfos(couponInfos);
            couponCombinations.add(combination);
        }
        return couponCombinations;

    }

    /**
     * 递归回溯法求解
     *
     * @param dimValue 原始数据集合
     * @param index 当前执行的集合索引
     * @param result 结果集合
     * @param curList 当前的单个结果集
     */
    private void backtrace(List<List<CouponInfo>> dimValue, int index,
                           List<List<CouponInfo>> result, List<CouponInfo> curList) {
        if (curList.size() == dimValue.size())
            result.add(new ArrayList<>(curList));
        else
            for (int j = 0; j < dimValue.get(index).size(); j++) {
                curList.add(dimValue.get(index).get(j));
                backtrace(dimValue, index + 1, result, curList);
                curList.remove(curList.size() - 1);
            }
    }


    //将下面变成一个方法，普通券和外部券分别调用，分别得到礼券组合
    public List<CombinationCoupons> getpossibleCombination(Map<String, List<CouponInfo>> orderToCoupons){

        // 按orderId大小排列礼券列表
        Map<String, List<CouponInfo>> sortMap = new TreeMap<String, List<CouponInfo>>(new Comparator<String>(
        ) {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
        sortMap.putAll(orderToCoupons);
        List<List<CouponInfo>> list = new ArrayList<List<CouponInfo>>();
        for(String orderId : sortMap.keySet()){
            list.add(sortMap.get(orderId));
        }
        //按店铺维度，求礼券使用组合笛卡尔积（除跨店铺及全场通用礼券外，同一张礼券仅能用于一个店铺）
        List<CombinationCoupons> couponCombinations = descartes(list);
        //去除跨店铺礼券以外的重复组合
        for(CombinationCoupons combination:couponCombinations){
            List<CouponInfo> duplicateCoupon = new ArrayList<>();
            if(combination.getCouponInfos() == null){
                continue;
            }
            for(CouponInfo coupon:combination.getCouponInfos()){
                if(!duplicateCoupon.contains(coupon)){
                    duplicateCoupon.add(coupon);
                    continue;
                }
                if(coupon.getIsCrossOrder() == null || !coupon.getIsCrossOrder().equals("1")){
                    combination.setRepeatedCombination(true);
                    break;
                }
            }
        }
        //跨店铺礼券使用规则（如果一个店铺使用了全场通用券或跨店铺，相应店铺必须共享该礼券）
        List<String> allOrderIds = new ArrayList<>();
        for(String orderId : sortMap.keySet()){
            allOrderIds.add(orderId);
        }
        int size = sortMap.keySet().size();
        for(CombinationCoupons combination:couponCombinations){
            boolean hasFind = false;
            if(combination.getCouponInfos() == null || combination.isRepeatedCombination()){
                continue;
            }
            for(CouponInfo coupon:combination.getCouponInfos()){
                if(hasFind){break;}
                if(coupon.getIsCrossOrder() == null || !coupon.getIsCrossOrder().equals("1")){
                    continue;
                }
                //跨店铺券适用订单
                List<String> currOrderIds = getCouponUseRange(coupon);
                for(String currOrderId:currOrderIds){
                    if(hasFind){break;}
                    for(int i = 0; i < size; i++){
                        if(!allOrderIds.get(i).equals(currOrderId)) {
                            continue;
                        }
                        if(!combination.getCouponInfos().get(i).getCouponNum().equals(coupon.getCouponNum())){
                            combination.setIllegalCombination(true);;
                            hasFind = true;
                            break;
                        }
                    }
                }
            }
        }
        //非法组合为存在多张跨店铺券分情况处理
        for(CombinationCoupons combination:couponCombinations){
            if(combination.getCouponInfos() == null || !combination.isIllegalCombination()){
                continue;
            }
            Money maxMoney = new Money(0);
            CouponInfo maxCouponInfo = new CouponInfo();
            List<CouponInfo> crossCouponInfos = new ArrayList<>();
            for(CouponInfo coupon:combination.getCouponInfos()){
                if(coupon.getIsCrossOrder() != null && coupon.getIsCrossOrder().equals("1")){
                    crossCouponInfos.add(coupon);
                }
                if(coupon.getUsableMoney().greaterThan(maxMoney)){
                    maxMoney.setAmount(coupon.getUsableMoney().getAmount());
                    maxCouponInfo = coupon;
                }

            }
            //全部为跨店铺券，保留面额最大的一张
            if(crossCouponInfos.size() == combination.getCouponInfos().size()){
                combination.getCouponInfos().clear();
                for(int i=0;i<crossCouponInfos.size();i++){
                    combination.getCouponInfos().add(maxCouponInfo);
                }
            }else{//部分跨店铺券，则保留跨店铺以外的非跨店铺券
                for(int i = 0;i<combination.getCouponInfos().size();i++){
                    for(CouponInfo crossCoupon:crossCouponInfos){
                        if(combination.getCouponInfos().get(i) != null && combination.getCouponInfos().get(i).getCouponNum().equals(crossCoupon.getCouponNum())){
                            combination.getCouponInfos().set(i, null);
                        }
                    }
                }
            }
            combination.setIllegalCombination(false);
        }

        return couponCombinations;
    }


    private List<String> getCouponUseRange(CouponInfo coupon) {
        List<String> useRanges = new ArrayList<String>();
        if (coupon == null || StringUtil.isEmpty(coupon.getValidForOrder())) {
            return useRanges;
        }
        try {
            String[] urs = coupon.getValidForOrder().split("\\|")[0].replaceFirst("order_ids:", "").split(",");
            if (urs == null || urs.length == 0) {
                return useRanges;
            }
            for (String ur : urs) {
                useRanges.add(ur);
            }
        } catch (Exception e) {
            log.error("换取礼券使用范围出错。error:{}", e);
        }
        return useRanges;
    }


}
